// Created by 86176 on 2021/11/3.
//

#ifndef CHENYUENEW_IOBUFFER_H
#define CHENYUENEW_IOBUFFER_H


//#include <minwindef.h>
//#define BYTE unsigned char
/*#ifndef BYTE
//#define BYTE int
//#define BYTE unsigned char
#endif*/
#include <cstdlib>
#include <string>
#include <Winsock2.h>
#include <iostream>
#include <atlstr.h>
//#include <bitset>
//#include <cstddef>


class IoBuffer {
public:
    BYTE *byteStream;
    int capacity;
    int position,mark,limit;
    IoBuffer(){
        //初始状态为写状态
        byteStream = static_cast<BYTE *>(malloc(sizeof(BYTE) * 10000));
        memset(byteStream,'\0',10000);
        position = 0;
        mark = -1;
        capacity = 10000-1;
        limit = capacity;
    }
    explicit IoBuffer(int size){
        //初始状态为写状态
        byteStream = static_cast<BYTE *>(malloc(sizeof(BYTE) * size));
        memset(byteStream,'\0',size);
        position = 0;
        mark = -1;
        capacity = size-1;
        limit = capacity;
    }
    ~IoBuffer(){
        free(byteStream);
    }
    //position指向数据首部，设置清空
    IoBuffer* clear(){
        position = 0;
        limit = capacity;
        mark = -1;
        return this;
    }
    //设置读模式，position指向数据首部，并且limit指向数据尾部
    IoBuffer* filp(){
        if(limit != capacity) return this;
        limit = position;
        position = 0;
        mark = -1;
        return this;
    }
    //postion指向缓冲区的数据末尾，写模式,读取完之后做一个压缩
    IoBuffer* compact(){
        memcpy(byteStream,byteStream+position,limit-position);
        position = limit -position;
        limit = capacity;
        mark = -1;
        return this;
    }
    //记录当前位置
    void markPos(){
        mark = position;
    }
    //还原当前位置
    void remarkPos(){
        if(-1 == mark) return;
        position = mark;
    }
    /*BYTE* getBufferByte(int len){
        BYTE *bytes = new BYTE[len+1];
        memcpy(bytes,byteStream+position,len);
        position+=len;
        return bytes;
    }*/
    std::string getString(int len){
        std::string str((char*)byteStream+position,len);
        position+=len;
        //str.Format(_T("%s"),len);
        return str;
    }
    //传递给指定地址数据
    int getBuffer(BYTE *p, int len){
        memcpy(p,byteStream+position,len);
        p[len] = '\0';
        position+=len;
        return len;
    }
    //写入值1
    int writeBuffer(BYTE *p){
        int len = sizeof(p)/sizeof(BYTE);
        std::cout<<"len:"<<len;
        memcpy(byteStream+position,p,len);
        position+=len;
        return len;
    }
    //写入值2
    int writeBuffer(BYTE *p, int len){
        memcpy(byteStream+position,p,len);
        position+=len;
        return len;
    }
    //从指定位置开始写入
    BYTE* getWriteIndexP(){
        return byteStream+position;
    }
    //获得buff的数据长度
    int getBufferLen(){
        if(limit == capacity){
            //写模式
            return position+1;
        }else{
            //读模式
            return limit - position + 1;
        }
    }

    //获得和获得
    BYTE getByte(){
        if(limit-position>=1){
            BYTE byte1 = *(byteStream+position);
            position++;
            return byte1;
        }else
            return 0;
    };
    void setByte(BYTE byte1){
        *(byteStream+position) = byte1;
        position++;
        return;
    };
    short getShort(){
        if(limit-position>=2){
            short len =  *(byteStream+position);
            position+=2;
            return len;
        }else
            return 0;
    };
    short setShort(){};
    int getInt(){
        int value;
        value = (int) ((*(byteStream+position) & 0xFF)
                       | ((*(byteStream+position+1) & 0xFF)<<8)
                       | ((*(byteStream+position+2) & 0xFF)<<16)
                       | ((*(byteStream+position+3) & 0xFF)<<24));
        position+=4;
        return value;
    };
    int setInt(int value){
        *(byteStream+position) =  (byte) (value & 0xFF);
        *(byteStream+position+1) =  (byte) ((value>>8) & 0xFF);
        *(byteStream+position+2) =  (byte) ((value>>16) & 0xFF);
        *(byteStream+position+3) =  (byte) ((value>>24) & 0xFF);
        position+=4;
    };
    /*float getFloat(){
        if(limit-position>=4){
            position+=8;
            return (float)(byteStream+position);
        }else
            return 0;
    };
    float setFloat(){};*/
    long getLong(){
        if(limit-position>=8){
            position+=8;
            return (long)(byteStream+position);
        }else
            return 0;
    };
    long setLong(){};
    double getDouble(){};
    double setDouble(){};
    bool getBool(){};
    bool setBool(){};



};


#endif //CHENYUENEW_IOBUFFER_H
